-
Notifications
You must be signed in to change notification settings - Fork 0
Implement OpenTracing-like tracer #47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Any new visualisations based on lots of lots of data??? @Abby010 and make sure you are copying over and synthesizing the details I have earlier. |
Not yet, I starting getting some dependency errors so I needed to fix that but I have started working with lots of data. |
New video links have been added with more data in the description |
Add comments rather than editing spec for that stuff. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most changes are just code style changes. As a summary:
- use
undefined
for null-ish fields - check if a value is undefined or not by doing a
== null
or!= null
check (yes, even though we haveundefined
as the type) - use single quotes
- ensure import formatting
- for array types, always wrap it in
Array<>
- for potentially undefined fields use
?
, unless you are unable to use?
for the parameter type, in which case you always useType | undefined
(as opposed tonull
)
@Abby010 can you:
I think it's important for testing why seed nodes are crashing. Also why use |
Also you should be assigning yourself. |
Start adding tests too. |
And benchmarks. I want a plan as of next cycle. |
src/lib/span.ts
Outdated
constructor(name: string, parentSpanId: string | null = null) { | ||
this.spanId = `span-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`; | ||
this.name = name; | ||
this.startTime = Date.now(); | ||
this.endTime = null; | ||
this.parentSpanId = parentSpanId; | ||
this.children = []; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only things that need to be set in the constructor are things that need the be passed through the constructor. Any other property can be defaulted when defined above with public startTime: number = Date.now()
The spanId
should be an IdSortable
from @matrixai/id
library.
Make sure that the span structure can be streamed into an incremental jsonl format. This is what we will be using to then stream visualise on the browser. @shafiqihtsham can weigh in if you talk to him about it. But I want you to write out a plan for implementation in Polykey-CLI by today. |
Tracing Integration PlanPhase 1: Integrate Tracing into js-logger as a First-Class Component
Add Incremental Span Streaming to JSONL
Phase 2: Integrate Tracer with Polykey CLI and Lifecycle Events
|
Your phase 2 doesn't mention https://github.com/MatrixAI/js-async-init at all. You both need to talk about the implementation plan with @tegefaulkes since I think you're missing some contextual details critical to understanding how tracing can be applied to Polykey's runtime. |
Phase 2 Plan: Polykey CLI Tracing IntegrationObjectiveInstrument the Polykey CLI runtime using the Tracer to support structured, memory-safe, and streamable observability of system behavior — with minimal invasiveness and full reversibility. 1. Embed Tracer into Polykey CLI Runtime
2. Hook into Lifecycle Events via js-async-initUtilize @AsyncInit decorators and structured lifecycle events defined in the js-async-init library. For async-initialized components like NodeConnectionManager, VaultManager, Daemon, etc., hook into their lifecycle using:
Instrumentation Pattern: nodeManager.addEventListener(events.NodeConnectionManagerStart.name, () => {
nodeManager.span = parentSpan.getChild('NodeManagerStart');
});
nodeManager.addEventListener(events.NodeConnectionManagerStop.name, () => {
nodeManager.span.end();
}); 3. Adopt Span Object Model (No Global Tracking)Replace global tracer calls with direct Span object usage. Example:
Track spans via objects, not IDs. Avoid propagating span IDs through business logic. 4. Stream Output Instead of Writing DirectlyRefactor Tracer to emit to a writable stream (WritableStream, PassThrough, etc.). Consumers of the stream (e.g., file writer, stderr, custom logger) decide how to handle the data. CLI Support:
5. Memory Management: No activeSpans, Use WeakRefsRemove Map<string, Span> used for global span tracking. Use WeakRef where necessary for parent-child relationships. 6. Implement Observable Tracing EventsTracer emits observable events: span:start Useful for real-time debugging, TUI enhancements, or plugin systems. 7. Testing Strategy: Use fast-check for Randomized Span BehaviorReplace Math.random() in test harnesses with fast-check property-based fuzzing. Supports reproducible failures and automated test shrinking for minimal failing cases. 8. Visual Debugging with TUI (as-is)No changes needed to TUI. Continues to read from the .jsonl file. 9.Leveraging js-async-init's Lifecycle ContractsUse lifecycle annotations from js-async-init to instrument long-lived services and ephemeral agents with start/stop or create/destroy lifecycles. The Tracer will hook into lifecycle phases without modifying the business logic directly. Each lifecycle boundary maps naturally to a span (e.g., VaultManagerStart, DaemonCreate, NodeConnectionDestroy).
|
Some things to review:
|
Reviewing https://github.com/tc39/proposal-async-context shows that:
@Abby010 feedback? |
Key thing about this is that our spans don't necessarily end to be useful. |
Re: async_context Proposal Agreed for now, relying solely on Node-specific behavior would limit portability. Since js-logger should remain runtime-agnostic, we shouldn’t hard-bind to Node.js-only primitives. Re: Span Should Be More Implicit
This would allow something like:
Re: Monkey Patching in Polykey Runtime This will let us test the conceptual model before formalizing APIs or integrations. Re: js-contexts + js-async-init Hybrid |
current.flags = fc.sample(flagArb, 1)[0]; | ||
current.parentId = openSpan(`Parent-${parentIndex}`); | ||
nestedIds = []; | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of sampling like this, I would recommend doing something like taking the current Unix time and using that as the seed, and increase the value by one every time you want to sample something new. You should also print the seed value to the console. This will ensure that you are using randomised values every time, and if something goes wrong, you can copy-paste the seed to get the same values to investigate why things went wrong. You should fix an error which happens once in a few runs, as that is an edge case you need to consider instead of rerunning the test and ignoring it.
Otherwise you've done pretty good integrating fast-check into this test.
The original plan was for @aryanjassal to start using this in Polykey regardless of the merge. But if that's too difficult. Start merging this in now incrementally and release new ones so that PK can start testing it. This week it has to be done. There's no more time to be allocated to this. |
@aryanjassal you now take over this PR to force it to be merged and released. |
@aryanjassal start squashing and merge into a patch version, then use it in a new PR in Polykey-CLI. |
Due to not having sufficient time for the handover from abby, there might be some minor issues which might make it to staging. This might see a lot of iteration as well. All the iteration will be done in patch updates which will be used by Polykey CLI. The |
I've cleaned up the codebase a little bit, so this can now be merged to staging. I will need to go over some things with abby about the future plans of the tracer, but until then I can start testing out monkey-patching. It doesn't make much sense to make a PR for this as the change will be in node modules, which is local-only and making a PR will not make a difference. I will however make a branch for this and push up a PR if any significant changes are made in there. |
fix: logical mode fix: time based mode chore: removed unnecessary comments fix: package-lock.json chore: deleted unnecessary asciinema recordings fix: package.json
chore: addressed PR comments
chore: cleaning up codebase chore: removed json files fix: lint
59f78a9
to
b40f6fb
Compare
Description
This program visualizes real-time execution flow of distributed spans in a terminal-based UI (TUI) using React Ink. It allows users to toggle between time-based (--sample 1s) and logical event-based (--sample logical) views while displaying structured span hierarchies with box-drawing characters.
Issues Fixed
Tasks
Final checklist
Terminal 1: --sample logical
Terminal 2: --sample 1s